import { Viewer } from "cesium";
import {
  assign,
  defaultConfig,
  handleClearEventByViewer,
  handleLeftClickEventByViewer,
  handleDoubleClick,
  handleRightClickEventByViewer,
  isString,
  isObject,
} from "yt-cesium";

const viewerMap: Map<string, Viewer> = new Map();

const { DEFAULT_VIEWER_NAME, eventConfig, viewerConfig } = defaultConfig;

type ViewerOpt = {
  leftClick?: boolean;
  rightClick?: boolean;
  clearEvent?: boolean;
  doubleClick?: boolean;
};

export type ViewerNameType = string | Viewer;

type CreateViewerType = Viewer.ConstructorOptions & ViewerOpt;

export function createViewer(name?: string, opt?: CreateViewerType): Viewer;
export function createViewer(opt?: CreateViewerType): Viewer;

/**
 * 创建Viewer实例 并开启部分配置
 * @param name
 * @param opt
 */
export function createViewer(
  name?: string | CreateViewerType,
  opt?: CreateViewerType
) {
  let _name = DEFAULT_VIEWER_NAME;
  let _opt = opt ?? {};
  if (isObject(name)) {
    _opt = name;
  } else if (isString(name)) {
    _name = name;
  }
  const {
    leftClick = eventConfig.defaultLeftClick,
    rightClick = eventConfig.defaultRightClick,
    doubleClick = eventConfig.defaultDoubleClick,
    ...others
  } = _opt;
  const viewer = new Viewer(
    DEFAULT_VIEWER_NAME,
    assign({}, viewerConfig, others)
  );
  viewerMap.set(_name, viewer);
  if (leftClick) {
    handleLeftClickEventByViewer(viewer);
  }
  if (rightClick) {
    handleRightClickEventByViewer(viewer);
  }
  if (doubleClick) {
    handleDoubleClick(viewer);
  }
  return viewer;
}

/**
 * 获取视图
 * @param viewerName
 */
export function getViewer(
  viewerName: ViewerNameType = DEFAULT_VIEWER_NAME
): Viewer {
  if (isString(viewerName)) {
    return viewerMap.get(viewerName)!;
  }
  return viewerName;
}

/**
 * 判断是不是指定的视图
 * @param viewer
 */
export function isViewer(viewer: any): viewer is Viewer {
  return viewer instanceof Viewer;
}

/**
 * 清除viewer实例
 * @param viewerName
 */
export function handlerClear(viewerName?: ViewerNameType) {
  handleClearEventByViewer(getViewer(viewerName));
}

/**
 * 摧毁视图
 * @param viewerName
 */
export function destroyViewer(viewerName: string) {
  const viewer = viewerMap.get(viewerName);
  viewer?.destroy();
  viewerMap.delete(viewerName);
}
